home *** CD-ROM | disk | FTP | other *** search
/ The 640 MEG Shareware Studio 2 / The 640 Meg Shareware Studio CD-ROM Volume II (Data Express)(1993).ISO / clang / 16550.zip / PORT_ID.C < prev   
Text File  |  1991-07-20  |  4KB  |  96 lines

  1. /* port_id.c    1/18/89   Louis Shay
  2.  
  3.    National Semiconductor Corporation
  4.    Microcomuputer Systems Division
  5.    Microcontroller Applications Group
  6.  
  7.    Program to identify the presence and type of UART in a system.
  8.    This program will query the serial port at global port address
  9.    "int ubase", and return a value that identifies what type of UART
  10.    is present at that address. This address is set by the calling program
  11.    prior to the function call. The returned int values are:
  12.  
  13.      0, if there is no identifiable UART at that port address.
  14.      1, if the port type is INS8250, INS8250-B.
  15.      2, if the port type is INS8250A, INS82C50A, NS16450, NS16C450.
  16.      3, if the port type is NS16550A.
  17.      4, if the port type is NS16C552.
  18.  
  19.   note: the main source file should include "ns16550a.h". This is the
  20.   device header file.
  21. */
  22. #include <stdio.h>
  23. #include <conio.h>
  24. #include "ns16550a.h"
  25.  
  26. int port_id()
  27. {
  28.   extern int ubase;                     /* reference global address */
  29.  
  30.  
  31.   /* 1. test general functionality. Is the core register set present? */
  32.  
  33.  
  34.   wrLCR( 0xaa );
  35.   if( rdLCR() != 0xaa )         /* test LCR register & set DLAB=1 */
  36.     return( 0 );
  37.  
  38.   /* as an identifier, UART address 1 is 8-bits (DLM) when LCR7=1 (DLAB).
  39.      UART address 1 is 4-bits (IER) when DLAB=0. */
  40.  
  41.   wrDLM( 0x55 );                        /* test for DLM present (8-bits) */
  42.   if( rdDLM() != 0x55 )
  43.     return( 0 );
  44.   wrLCR( 0x55 );                        /* LCR: set DLAB = 0 */
  45.   if( rdLCR() != 0x55 )
  46.     return( 0 );
  47.   wrIER( 0x55 );                        /* test for IER present (4-bits) */
  48.   if( rdIER() != 0x05 )
  49.     return( 0 );
  50.   wrFCR( 0 );                           /* FIFOs off, if present */
  51.   wrIER( 0 );                           /* interrupts off, IIR should be 01 */
  52.   if( rdIIR() != 1 )
  53.     return( 0 );
  54.  
  55.   /* test modem control register address. Should be 5-bits wide */
  56.  
  57.   wrMCR( 0xf5 );                        /* 8-bit write */
  58.   if( rdMCR() != 0x15 )                 /* expect 5-bit read */
  59.     return( 0 );
  60.  
  61.   /* test MCR/MSR loopback functions */
  62.  
  63.   wrMCR( 0x10 );                        /* set loop mode */
  64.   (void)rdMSR();                        /* clear out delta bits */
  65.   if( ( rdMSR() & 0xf0 ) != 0 )         /* check state bits */
  66.     return( 0 );
  67.   wrMCR( 0x1f );                        /* toggle modem control lines */
  68.   if( ( rdMSR() & 0xf0 ) != 0xf0 )      /* check state bits */
  69.     return( 0 );
  70.   wrMCR( 0x03 );                        /* exit loop mode, DTR, RTS active */
  71.  
  72.   /* 2. port id successful at this point. determine port type */
  73.  
  74.   wrSCR( 0x55 );                        /* is there a scratch register? */
  75.   if( rdSCR() != 0x55 )
  76.     return( 1 );                        /* no SCR, type = INS8250 */
  77.  
  78.   wrFCR( 0xcf );                        /* enable FIFO's, if present */
  79.   if( ( rdIIR() & 0xc0 ) != 0xc0 )      /* check FIFO ID bits */
  80.     return( 2 );                        /* no FIFO's, type = NS16450 */
  81.   wrFCR( 0 );                           /* turn off FIFO's */
  82.  
  83.   wrLCR( 0x80 );                        /* set DLAB */
  84.   wrAFR( 0x07 );                        /* write to AFR */
  85.   if ( rdAFR() != 0x07 ) {              /* read AFR */
  86.      wrLCR( 0x00 );                        /* reset DLAB */
  87.      return ( 3 );                      /* if not the same, type = NS16550A */
  88.    }
  89.   wrAFR( 0x00);                         /* clear AFR */
  90.   wrLCR( 0x00 );                        /* reset DLAB */
  91.   return ( 4 );                         /* type = NS16C552 */
  92. }
  93.  
  94.  
  95.  
  96.